package com.hzgj.bcl.soa.command;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.hzgj.bcl.soa.collector.Collectors;
import com.hzgj.bcl.soa.collector.JmxCollector;
import com.hzgj.bcl.soa.util.Triple;
import com.hzgj.bcl.util.lang.StrKit;

import java.rmi.ConnectException;
import java.util.Map;

/**
 * Created by Administrator on 2016/9/18.
 */
public abstract class JmxInvokeCommand extends BaseCommand {

    @Override
    public String invoke(CommandOptions commandOptions) {
        Map<String, Object> result = Maps.newHashMap();
        String ip = null;
        String port = null;
        try {
            Triple<JmxCollector, String, String> triple = getJmxConnection(commandOptions);
            ip = triple.getMiddle();
            port = triple.getRight();
            result.put("ip", ip);
            result.put("port", port);
            result.putAll(jmxInvoke(triple.getLeft(), commandOptions, ip, port));
        } catch (ConnectException e) {
            Collectors.removeCollector(ip, Integer.parseInt(port));
        } catch (Exception e) {
            logger.error("{}", e);
            result.put("message","更新失败");
        }
        return JSON.toJSONString(result);
    }

    <T> T invoke0(CommandOptions commandOptions) {
        Triple<JmxCollector, String, String> triple = getJmxConnection(commandOptions);
        try {
            return (T) jmxInvoke(triple.getLeft(), commandOptions, triple.getMiddle(), triple.getRight());
        } catch (ConnectException e) {
            Collectors.removeCollector(triple.getMiddle(), Integer.parseInt(triple.getRight()));
        }
        return null;
    }

    Triple<JmxCollector, String, String> getJmxConnection(CommandOptions commandOptions) {
        String address = commandOptions.params.get("address")[0];
        String jmxPort = commandOptions.params.get("jmxPort")[0];
        if (StrKit.isBlank(jmxPort) && StrKit.isBlank(address)) {
            throw new IllegalArgumentException("address must be exist");
        }
        String[] _address = address.split(":");
        String port = _address[1];
        String host = _address[0];
        return new Triple<>(getJmxCollector(host, Integer.parseInt(jmxPort)), host, port);
    }

    public JmxCollector getJmxCollector(String host, int jmxPort) {
        JmxCollector jmxCollector = Collectors.getCollector(host, jmxPort);
        if (jmxCollector == null) {
            throw new RuntimeException("create jmx connection with ip=" + host + ",port=" + jmxPort + " failure.");
        }
        return jmxCollector;
    }

    abstract Map<String, Object> jmxInvoke(JmxCollector jmxCollector, CommandOptions commandOptions, String host, String port) throws ConnectException;
}
